package org.gruposp2p.proyectokarma.gwt.client.json;

import java.util.HashSet;
import java.util.Set;
import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONNull;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONValue;
import org.gruposp2p.proyectokarma.gwt.client.domain.CometdMetaMessage;
import org.gruposp2p.proyectokarma.gwt.client.domain.Document;
import org.gruposp2p.proyectokarma.gwt.client.domain.Peer;
import org.gruposp2p.proyectokarma.gwt.client.domain.Tag;
import org.gruposp2p.proyectokarma.gwt.client.util.DateUtils;

import static org.gruposp2p.proyectokarma.gwt.client.json.JSONConstants.*;

public class JSONToDomain {
	
    public JSONToDomain () {}

    public static CometdMetaMessage getCometdMetaMessage(JSONValue jsonValue) {
    	CometdMetaMessage message = new CometdMetaMessage();
        JSONObject jsonObject;
        JSONValue value;
        if ((jsonObject = jsonValue.isObject() ) != null) {
            if ((value = jsonObject.get(CHANNEL)) != null) {
            	message.channel = value.isString().stringValue();
            } if ((value = jsonObject.get(CLIENT_ID)) != null) {
            	message.clientId = value.isString().stringValue();
            } if ((value = jsonObject.get(VERSION)) != null) {
            	message.version = value.isString().stringValue();
            } if ((value = jsonObject.get(SUCCESSFUL)) != null) {
            	message.successful = value.isBoolean().booleanValue();//Boolean.valueOf(value.isString().stringValue())
            }
            if ((value = jsonObject.get(MINIMUM_VERSION)) != null) {
            	message.minimumVersion = value.isString().stringValue();
            } 
            if ((value = jsonObject.get(ID)) != null) {
            	message.id = value.isString().stringValue();
            } 
            if ((value = jsonObject.get(SUPPORTED_CONNECTION_TYPES)) != null) {
            	JSONArray array = value.isArray();
            	String[] strResult= new String[array.size()];
            	for (int i = 0; i < array.size(); i++) {
            		strResult[i] = array.get(i).isString().stringValue();
            	}
            	message.supportedConnectionTypes = strResult;
            } if ((value = jsonObject.get(REESTABLISH)) != null) {
            	message.reestablish = value.isBoolean().booleanValue();//Boolean.valueOf(value.isString().stringValue())
            } 
            if ((value = jsonObject.get(ACTION)) != null) {
            	message.action = value.isString().stringValue();
            }	
            if ((value = jsonObject.get(SUBSCRIPTION)) != null) {
            	message.subscription = value.isString().stringValue();
            }
        }       
        return message;
    }
    
    public static Peer getPeer(JSONValue jsonValue) {
    	Peer peer = new Peer();
        JSONObject jsonObject;
        JSONValue value;
        JSONArray jsonArray;
		Log.debug("jsonValue: " + jsonValue);
        if ((jsonArray = jsonValue.isArray() ) != null) {
        	jsonObject = jsonArray.get(0).isObject();
            if ((value = jsonObject.get(PEER_ID)) != null) {
            	peer.setId(new Double(value.isNumber().doubleValue()).longValue());
            } if ((value = jsonObject.get(PEER_EMAIL)) != null 
            		&& !(value.isNull() instanceof JSONNull)) {
            	peer.setEmail(value.isString().stringValue());
            } if ((value = jsonObject.get(PEER_USERNAME)) != null) {
            	peer.setUsername(value.isString().stringValue());
            }
        }
    	return peer;
    }

    public static Document getDocument(JSONValue jsonValue) {
    	Document document = new Document();
        JSONObject jsonObject;
        JSONValue value;
        if ((jsonObject = jsonValue.isObject() ) != null) {
            if ((value = jsonObject.get(DOCUMENT_ID)) != null) {
            	document.setId(new Double(value.isNumber().doubleValue()).longValue());
            } if ((value = jsonObject.get(DOCUMENT_PEER)) != null) {
            	document.setPeer(new Double(value.isNumber().doubleValue()).longValue());
            } if ((value = jsonObject.get(DOCUMENT_PEER_NAME)) != null) {
            	document.setPeerName(value.isString().stringValue());
            }  if ((value = jsonObject.get(DOCUMENT_NAME)) != null) {
            	document.setName(value.isString().stringValue());
            } if ((value = jsonObject.get(DOCUMENT_CONTENT)) != null) {
            	document.setContent(value.isString().stringValue());
            } if ((value = jsonObject.get(DOCUMENT_DATE_CREATED)) != null) {
            	document.setDateCreated(DateUtils.getDateFromSimpleString(
            			value.isString().stringValue()));
            } if ((value = jsonObject.get(DOCUMENT_LAST_UPDATE)) != null) {
            	document.setLastUpdated(DateUtils.getDateFromSimpleString(
            			value.isString().stringValue()));
            } if ((value = jsonObject.get(DOCUMENT_IS_POLLING)) != null) {
            	document.setPolling(value.isBoolean().booleanValue());
            } if ((value = jsonObject.get(DOCUMENT_TAGS)) != null) {
                JSONArray jsonArray;
            	if ((jsonArray = value.isArray()) != null) { 
            		Set<String> tags = new HashSet<String>();
                	for (int i = 0; i < jsonArray.size(); ++i) {
                		tags.add(jsonArray.get(i).isString().stringValue());
                	}
                	document.setTags(tags);
            	}
            }
            
            
        }
    	return document;
    }
    
    public static Set<Document> getDocuments(JSONValue jsonValue) {
    	Set<Document> documentSet = null;
        JSONObject jsonObject;
        JSONValue objectReceived;
        JSONValue jsonDocumentValue;
        JSONArray jsonArray;
        if ((jsonObject = jsonValue.isObject()) != null) {
        	objectReceived = jsonObject.get(DOCUMENTS);
        	documentSet = new HashSet<Document>();
        	if ((jsonArray = objectReceived.isArray()) != null) {
            	for (int i = 0; i < jsonArray.size(); ++i) {
            		jsonDocumentValue = jsonArray.get(i);
            		Document document = getDocument(jsonDocumentValue);
            		documentSet.add(document);
            	}
        	}
        }
        return documentSet;
    }
    
    public static Set<Tag> getTags(JSONValue jsonValue) {
    	Log.debug("JSONToDomain.getTags - jsonValue: " + jsonValue);
    	Set<Tag> tagSet = null;
        JSONObject jsonObject;
        JSONValue objectReceived;
        JSONValue jsonTagValue;
        JSONArray jsonArray;
        if ((jsonObject = jsonValue.isObject()) != null) {
        	objectReceived = jsonObject.get(TAGS);
        	tagSet = new HashSet<Tag>();
        	if ((jsonArray = objectReceived.isArray()) != null) {
            	for (int i = 0; i < jsonArray.size(); ++i) {
            		jsonTagValue = jsonArray.get(i);
            		Tag tag = getTag(jsonTagValue);
            		tagSet.add(tag);
            	}
            } else if ((jsonValue.isObject()) != null) {
            	Tag tag = getTag(jsonValue);
            	tagSet.add(tag);
            }
        }	
    	return tagSet;
    }
    
    public static Tag getTag(JSONValue jsonValue) {
    	Tag tag = new Tag ();
        JSONObject jsonObject;
        JSONValue value;
        if ((jsonObject = jsonValue.isObject() ) != null) {
            if ((value = jsonObject.get(TAG_ID)) != null) {
            	tag.setId(Double.valueOf(
            			value.isNumber().doubleValue()).longValue()) ;
            }         	
            if ((value = jsonObject.get(TAG_NAME)) != null)
            	tag.setName(value.isString().stringValue());
            if ((value = jsonObject.get(TAG_FRECUENCY)) != null) {
            	tag.setFrequency(Double.valueOf(
            			value.isNumber().doubleValue()).intValue());
            }
        }       
    	return tag;
    }
}